home *** CD-ROM | disk | FTP | other *** search
- (*$N+*)
- program BGIGrapher;
-
- uses
- Crt, Dos, Graph;
-
- Const
- MaxData = 600;
-
- Type
- Data = array [1..MaxData] of Extended;
- GraphContents = Record
- X,Y:Data;
- XMin,XMax,YMin,YMax:Extended;
- AbsXMax,AbsYMax:Extended;
- end;
-
-
-
- var
- FileName,Labels: string;
- Graphs:GraphContents; (* Some important info. on data *)
- NoOfData,i,Starting,Ending:integer;
- GraphDriver : integer; (* The Graphics device driver *)
- GraphMode : integer; (* The Graphics mode value *)
- MaxX, MaxY : word; (* The maximum resolution of the screen *)
- ErrorCode : integer; (* Reports any graphics errors *)
- MaxColor : word; (* The maximum color value available *)
- OldExitProc : Pointer; (* Saves exit procedure address *)
-
-
- (* Display help screen *)
- procedure HelpScreen;
-
- begin
- Writeln ('FreeWare Experimental Grapher ');
- Writeln ('(C)opyright TakaPuna 1991 Version 1.1');
- Writeln ('Portions of the codes are (C)opyrighted by Borland International ');
- Writeln;
- Writeln ('Command Line Options:');
- Writeln (' FileName [All Labels] [Starting Ending Labels] ');
- Writeln;
- Writeln (' FileName : Data file from a text file ');
- Writeln (' Starting : Starting index to view (integer) ');
- Writeln (' Ending : Ending index to view (integer) ');
- Writeln (' Labels : Axis labels ');
- Writeln;
- Writeln ('Example:');
- Writeln ('- To display all points and label the axis as');
- Writeln (' "X vs Y" >: Grapher FileName All X vs Y ');
- Writeln ('- To display points #10 to #20 and label the axis as');
- Writeln (' "X vs Y" >: Grapher FileName 10 20 X vs Y ');
- Writeln ('- All parameter must appear in order !!!!');
- Halt (1);
- end;
-
-
- (*$F+*)
- (* Trap run time errors *)
- procedure UserExitProc;
- begin
- ExitProc := OldExitProc; (* Restore exit procedure address *)
- CloseGraph;
- end; (* UserExitProc *)
- (*$F-*)
-
-
- procedure Initialize;
- (* Initialize graphics and report any errors that may occur *)
- var
- InGraphicsMode : boolean; (* Flags initialization of graphics mode *)
- PathToDriver : string; (* Stores the DOS path to *.BGI & *.CHR *)
- begin
- (* when using Crt and graphics, turn off Crt's memory-mapped writes *)
- DirectVideo := False;
- OldExitProc := ExitProc; (* save previous exit proc *)
- ExitProc := @UserExitProc; (* insert our exit proc in chain *)
- PathToDriver := '';
- repeat
-
- (*$IFDEF Use8514*) (* check for Use8514 $DEFINE *)
- GraphDriver := IBM8514;
- GraphMode := IBM8514Hi;
- (*$ELSE*)
- GraphDriver := Detect; (* use autodetection *)
- (*$ENDIF*)
-
- InitGraph(GraphDriver, GraphMode, PathToDriver);
- ErrorCode := GraphResult; (* preserve error return *)
- if ErrorCode <> grOK then (* error? *)
- begin
- Writeln('Graphics error: ', GraphErrorMsg(ErrorCode));
- if ErrorCode = grFileNotFound then (* Can't find driver file *)
- begin
- Writeln('Enter full path to BGI driver or type <Ctrl-Break> to quit:');
- Readln(PathToDriver);
- end
- else
- Halt(1); (* Some other error: terminate *)
- end;
- until ErrorCode = grOK;
- MaxColor := GetMaxColor; (* Get the maximum allowable drawing color *)
- MaxX := GetMaxX; (* Get screen resolution values *)
- MaxY := GetMaxY;
- end; (* Initialize *)
-
-
- (* Returns true if file exists *)
- function FileExist (FileName:string):boolean;
-
- Var
- F:Text;
-
- begin
- (*$I-*)
- Assign (F,FileName);
- Reset (F);
- FileExist:= IOResult = 0;
- (*$I+*)
- end;
-
-
-
- function Int2Str(L : LongInt) : string;
- (* Converts integer to string *)
- var
- S : string;
- begin
- Str(L, S);
- Int2Str := S;
- end; (* Int2Str *)
-
-
- function Str2Int(S:string):integer;
- (* Converts string to integer *)
- var
- L,Code:integer;
-
- begin
- Val(S,L,Code);
- if Code <> 0 then
- begin
- Writeln ('Integer values expected as parameters.');
- Halt(1);
- end
- else
- Str2Int:=L;
- end;
-
-
- function Real2Str(L : Extended) : string;
- (* Converts Extended numbers to string *)
- var
- S : string;
- begin
- Str(L:0, S);
- Real2Str := S;
- end; (* Real2Str *)
-
- (* Check if the Parameter is equal to the Switch *)
- function IsEqual(Parameter,Switch:String):boolean;
-
- var
- Quit:boolean;
-
- begin
- Quit:=false;
- i:=0;
- While not Quit do
- begin
- Inc(i);
- Quit:=(Upcase(Switch[i])<>Upcase(Parameter[i])) or (i=Length(Switch));
- end;
- if i=Length(Switch) then
- IsEqual:=true
- else
- IsEqual:=false;
- end;
-
- procedure DefaultColors;
- (* Select the maximum color in the Palette for the drawing color *)
- begin
- SetColor(MaxColor);
- end; (* DefaultColors *)
-
-
- procedure FullPort;
- (* Set the view port to the entire screen *)
- begin
- SetViewPort(0, 0, MaxX, MaxY, ClipOff);
- end; (* FullPort *)
-
- procedure MainWindow(Header : string);
- (* Make a default window and view port for demos *)
- begin
- DefaultColors; (* Reset the colors *)
- SetTextStyle(SmallFont, HorizDir, 5);
- SetTextJustify(CenterText, TopText); (* Left justify text *)
- FullPort; (* Full screen view port *)
- OutTextXY(MaxX div 2,0, Header); (* Draw the header *)
- (* Draw main window *)
- SetViewPort (Round(0.2*MaxX),Round(0.1*MaxY),Round(0.9*MaxX),Round(0.7*MaxY),
- ClipOff);
-
- end; (* MainWindow *)
-
-
- procedure WaitToGo;
- (* Wait for the user to abort the program or continue *)
- const
- Esc = #27;
- var
- Ch : char;
- begin
- repeat until KeyPressed;
- Ch := ReadKey;
- if ch = #0 then ch := readkey; (* trap function keys *)
- if Ch = Esc then
- Halt(0) (* terminate program *)
- else
- ClearDevice; (* clear screen *)
-
- end; (* WaitToGo *)
-
-
-
- (* Initialize the Graph Record *)
- procedure InitGlobal (UserGivenFile:string);
-
- var
- FileName:text;
- j:integer;
- a,b:Extended;
- TXmax,TXmin,TYmax,TYmin:Extended;
- Quit:boolean;
-
- begin
- NoOfData:=0;
- j:=1;
- i:=1;
- ClrScr;
- Quit:=false;
- Assign (FileName,UserGivenFile);
- Reset (FileName);
- While not Quit do
- begin
- (*$I-*)
- Readln (FileName,a,b);
- (*$I+*)
- if IOResult = 0 then
- begin
- if ParamCount > 2 then
- begin
- if (j>=Starting) and (j<=Ending) then
- begin
- Graphs.X[i]:=a;
- Graphs.Y[i]:=b;
- Inc (NoOfData);
- Inc (i);
- end;
- end
- else
- begin
- Graphs.X[i]:=a;
- Graphs.Y[i]:=b;
- Inc (NoOfData);
- Inc(i);
- end;
- Inc(j);
- end
- else
- Writeln ('Some Invalid entries skipped ');
- Quit:=(NoOfData = MaxData) or (j=Ending) or EOF(FileName);
- end; (* While not Quit *)
- Close (FileName);
-
- if (NoOfData = MaxData) then
- begin
- Writeln ('Too many data .....Aborting program. Maximum data = ',MaxData);
- Halt(1);
- end
- else
-
- begin
- TXmax:=Graphs.X[1]; (* find the maximum and the minimum of data *)
- TXMin:=Graphs.X[1];
- TYMax:=Graphs.Y[1];
- TYMin:=Graphs.Y[1];
-
- for i:=1 to NoOfData do
- begin
- if Graphs.X[i] > TXMax then
- TXMax:=Graphs.X[i];
-
- if Graphs.X[i] < TXMin then
- TXMin:=Graphs.X[i];
-
- if Graphs.Y[i] > TYMax then
- TYMax:=Graphs.Y[i];
-
- if Graphs.Y[i] < TYMin then
- TYMin:=Graphs.Y[i];
- end;
-
- Graphs.XMax:=TXMax;
- Graphs.XMin:=TXMin;
- Graphs.YMax:=TYMax;
- Graphs.YMin:=TYMin;
-
- if Graphs.XMax= Graphs.XMin then
- begin
- Writeln ('Data does not make sense.');
- Halt(1);
- end;
-
- if (Abs(TXmin) > Abs(TXMax)) then
- Graphs.AbsXMax:=Abs(TXMin)
- else
- Graphs.AbsXMax:=Abs(TXMax);
-
-
- if (Abs(TYmin) > Abs(TYMax)) then
- Graphs.AbsYMax:=Abs(TYMin)
- else
- Graphs.AbsYMax:=Abs(TYMax);
-
-
- end;
-
- end; (* InitGlobal *)
-
-
- procedure Status(Msg : string);
- (* report the status of graph *)
-
- begin
- FullPort;
- DefaultColors;
- SetTextJustify(CenterText, TopText);
- SetLineStyle(SolidLn, 0, NormWidth);
- SetFillStyle(EmptyFill, 0);
- OutTextXY(MaxX div 2,MaxY-(TextHeight('M')+20),Msg);
- (* Draw main window back again *)
- SetViewPort (Round(0.2*MaxX),Round(0.1*MaxY),Round(0.9*MaxX),Round(0.7*MaxY),
- ClipOff);
-
- end; (* Status *)
-
-
- procedure DrawBorder;
- (* Draw a border around the current view port
- and labels the axis *)
- var
- ViewPort : ViewPortType;
- IncX,IncY,Start:Extended;
- Mult:Extended;
-
- begin
-
- if (Graphs.XMax > 0) and (Graphs.XMin >= 0) then
- IncX:=(Graphs.XMax-Graphs.XMin)/4;
- if (Graphs.XMax < 0) and (Graphs.XMin < 0) then
- IncX:=(-Abs(Graphs.XMax)+Abs(Graphs.XMin))/4;
- if (Graphs.XMax >= 0) and (Graphs.XMin < 0) then
- IncX:=(Abs(Graphs.XMax)+Abs(Graphs.XMin))/4;
-
- if (Graphs.YMax=Graphs.YMin) then
- IncY:=Abs(Graphs.YMax/4)
- else
- begin
- If (Graphs.YMax > 0) and (Graphs.YMin >= 0) then
- IncY:=(Graphs.YMax-Graphs.YMin)/4;
- If (Graphs.YMax < 0) and (Graphs.YMin < 0) then
- IncY:=(-Abs(Graphs.YMax)+Abs(Graphs.YMin))/4;
- if (Graphs.YMax >= 0) and (Graphs.YMin < 0) then
- IncY:=(Abs(Graphs.YMax)+Abs(Graphs.YMin))/4;
- end;
-
- Status ('Step size X = '+Real2Str(IncX)+
- ' Step size Y ='+Real2Str(IncY));
-
- DefaultColors;
- SetLineStyle(SolidLn,0, ThickWidth);
- GetViewSettings(ViewPort);
- SetTextStyle(SmallFont, HorizDir, 5);
- with ViewPort do
- begin
- Rectangle(0, 0, x2-x1, y2-y1);
-
- (* Rectangle edges *)
- Line (X2-X1+4,0,X2-X1-1,0);
- Line (0,-4,0,1);
- Line (0,Y2-Y1+4,0,Y2-Y1-1);
- Line (-4,0,1,0);
-
-
- (* Draw ticks on Y axis *)
- Mult:=0.25;
- for i:=1 to 4 do
- begin
- Line (X2-X1+4,Round(Mult*(Y2-Y1)),X2-X1-1,Round(Mult*(Y2-Y1)));
- Line (-4,Round(Mult*(Y2-Y1)),1,Round(Mult*(Y2-Y1)));
- Mult:=Mult+0.25;
- end;
-
- (* Label the Y Axis *)
- if (Graphs.YMax=Graphs.YMin) then
- Start:=Graphs.YMax-(2*IncY)
- else
- Start:=Graphs.YMin;
-
- Mult:=1;
- for i:=1 to 5 do
- begin
- OutTextXY (-4-TextWidth(Real2Str(Start)),Round(Mult*(Y2-Y1))-TextHeight(Real2Str(Start)),
- Real2Str(Start));
- Mult:=Mult-0.25;
- Start:=Start+IncY;
- end;
-
-
- (* Draw ticks on X axis *)
- Mult:=0.25;
- for i:=1 to 4 do
- begin
- Line (Round(Mult*(X2-X1)),-4,Round(Mult*(X2-X1)),1);
- Line (Round(Mult*(X2-X1)),Y2-Y1+4,Round(Mult*(X2-X1)),Y2-Y1-1);
- Mult:=Mult+0.25;
- end;
-
-
- (* Label the X axis *)
- Mult:=0;
- Start:=Graphs.Xmin;
- for i:=1 to 5 do
- begin
- OutTextXY (Round(Mult*(X2-X1))-TextWidth(Real2Str(Start)) div 4,Y2-Y1+TextHeight(Real2Str(Start)),
- Real2Str(Start));
- Mult:=Mult+0.25;
- Start:=Start+IncX;
- end;
-
- end; (* with ViewPort *)
-
- end; (* DrawBorder *)
-
-
-
- procedure ScaleData;
- (* Scale the data such that it will fall inside the viewport *)
-
- var
- ShiftX,ShiftY:integer;
- Xscale,YScale:Extended;
- ViewPort:ViewPortType;
-
- begin
- GetViewSettings(ViewPort);
- With ViewPort do
- begin
- (* Put some conditions on X *)
-
- if (Graphs.XMax > 0 ) and (Graphs.XMin > 0) then (* XMax > 0 *)
- begin (* XMin > 0 *)
- XScale:=(X2-X1)/(Graphs.XMax-Graphs.XMin);
- ShiftX:=-Round(Graphs.XMax*XScale-X2+X1);
- end
- else
- begin
- if Graphs.XMax > 0 then (* absolutely no zero *)
- begin
- ShiftX:=Round((1-(Graphs.XMax/(Graphs.XMax + Abs(Graphs.Xmin))))*(X2-X1));
- XScale:=(X2-(ShiftX+X1))/(Graphs.XMax);
- if XScale = 0 then
- XScale:=(X2-X1)/(Graphs.AbsXMax)
- end
- else
- begin
- XScale:=(X2-X1)/(Graphs.XMax-Graphs.XMin);
- ShiftX:=-Round(Graphs.XMax*XScale-X2+X1);
- end;
- end;
-
- (* Put Some condition on Y *)
- if (Graphs.YMax=Graphs.YMin) then
- begin
- for i:=1 to NoOfData do
- begin
- Graphs.X[i]:=Graphs.X[i]*XScale+ShiftX;
- Graphs.Y[i]:=0.5*(Y2-Y1);
- end;
- end
- else
- begin
- if (Graphs.YMax > 0 ) and (Graphs.YMin > 0) then (* YMax > 0 *)
- begin (* YMin > 0 *)
- YScale:=(Y2-Y1)/(Graphs.YMax-Graphs.YMin);
- ShiftY:=-Round(Graphs.YMax*YScale-y2+y1);
- end
- else
- begin
- if (Graphs.YMax > 0) then
- begin
- ShiftY:=Round((1-(Graphs.YMax/(Graphs.YMax + Abs(Graphs.Ymin))))*(Y2-Y1));
- YScale:=(Y2-(ShiftY+Y1))/Graphs.YMax;
- if YScale= 0 then
- YScale:=(Y2-Y1)/(Graphs.AbsYMax);
- end
- else
- begin
- YScale:=(Y2-Y1)/(Graphs.YMax-Graphs.YMin);
- ShiftY:=-Round(Graphs.YMax*YScale-y2+y1);
- end;
- end;
- for i:=1 to NoOfData do
- begin
- Graphs.X[i]:=Graphs.X[i]*XScale+ShiftX;
- Graphs.Y[i]:=Graphs.Y[i]*YScale+ShiftY;
- end;
- end;
- end;
-
- end; (* Scale Data *)
-
-
- procedure Plot;
- (* plot the given data in the array *)
-
- var
- ViewPort:ViewPortType;
-
- begin
- SetLineStyle(SolidLn, 0, NormWidth);
- GetViewSettings(ViewPort);
- With ViewPort do
- begin
- MoveTo (Round(Graphs.X[1]),
- (Y2-Y1)-Round(Graphs.Y[1]));
- for i:=2 to NoOfData do
- LineTo (Round(Graphs.X[i]),
- (Y2-Y1)-Round(Graphs.Y[i]));
- end;
- end; (* Plot *)
-
-
- (* Handles command line input *)
- procedure CommandLine;
-
- begin
- if ParamCount = 0 then
- HelpScreen
- else
- begin
- Labels:='';
- FileName:=ParamStr(1);
- if NOT FileExist(FileName) then
- begin
- Writeln ('File ',FileName,' does not exist.');
- Halt(1);
- end;
- if ParamCount > 2 then
- begin
- if Not (IsEqual(ParamStr(2),'All')) then
- begin
- Starting:=Str2Int(ParamStr(2));
- Ending:=Str2Int(ParamStr(3));
- if (Starting > Ending) then
- begin
- Writeln ('Starting index must be less than ending index. ');
- Halt(1);
- end;
- for i:=4 to ParamCount do
- Labels:=Labels +' '+ ParamStr(i);
- end
- else
- begin
- Starting:=1;
- Ending:=MaxData;
- for i:=3 to ParamCount do
- Labels:=Labels +' '+ ParamStr(i);
- end;
- end;
- end;
- end;
-
-
- begin (* program body *)
- ClrScr;
- CommandLine;
- InitGlobal (FileName);
- Initialize;
- MainWindow (Labels);
- ScaleData;
- DrawBorder;
- Plot;
- WaitToGo;
- end.